<?php 
/**
 * @package scottlib.criteria
 * @author Aaron Collegeman aaroncollegeman.com
 * @version 1.0.0-BETA
 * 
 * Copyright (C)2009 Collegeman.net, LLC.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 */

///////////////////////////////////////////////////////////////////////////////
// This file loads the criteria classes.
///////////////////////////////////////////////////////////////////////////////

/**
 * Base class for all types of query Criteria. 
 * 
 * @since 1.0.0-BETA
 */
class slCriteria {
	
	protected $criterion = array();
	
	protected $placeholders = array();
	
	/**
	 * The constructor accepts two types of parameters: either a
	 * single array, or an unlimited number of parameters.  The constructor
	 * determines which mode is being used by the parameter type of
	 * parameter 0: if it is an array, than all other parameters are
	 * ignored.
	 * 
	 * @param $aCriteria mixed Either an array of slCriteria objects,
	 * or the first of a series of slCriteria-typed parameters.
	 */
	function __construct($aCriteria) {
		$aCriteria = (is_array($aCriteria) ? $aCriteria : func_get_args());
		foreach($aCriteria as $crit) {
			$this->addCriteria($crit);
		}
	}
	
	final function addCriteria(slCriteria $crit) {
		$crit->addPlaceholders($this->placeholders);
		$this->criteron[] = $crit;
	}
	
	final function getCriterion() {
		return $this->criterion;
	}
	
	final function setPlaceholder($name, $value) {
		$this->placeholders[$name] = $value;
	}
	
	final function addPlaceholders($placeholders) {
		foreach($placeholders as $name => $value) {
			$this->placeholders[$name] = $value;
		}
	}
	
	final function getPlaceholders() {
		return $this->placeholders;
	}
	
	static final function import() {
		return 'global $criteria, $and, $or, $not, $if, $elseif, $else, $each, $projections, $eq, $ne, $lt, $gt, $le, $ge, $isNull, $isNotNull, $inList, $between, $eqProperty, $neProperty, $ltProperty, $gtProperty, $leProperty, $geProperty, $idEq, $like, $iLike, $isEmpty, $isNotEmpty, $order, $rLike, $sizeEq, $sizeNe, $sizeLt, $sizeGt, $sizeLe, $sizeGe, $property, $avg, $distinct, $countDistinct, $count, $groupProperty, $max, $min, $rowCount, $sum;';
	}
	
}

if (!function_exists('all_criteria')) {
	function all_criteria() {
		return slCriteria::import();	
	}
}


function sl_criteria($aCriteria) {
	$aCriteria = (is_array($aCriteria) ? $aCriteria : func_get_args());
	return new slCriteria($aCriteria);
}

$criteria = 'sl_criteria';

/**
 * A logical AND clause.
 * 
 * This class is essentially a marker, as it does nothing other
 * than subclass the slCriteria base class.
 * 
 * @since 1.0.0-BETA
 */
final class slAndCriteria extends slCriteria {}

function sl_and($aCriteria) {
	$aCriteria = (is_array($aCriteria) ? $aCriteria : func_get_args());
	return new slAndCriteria($aCriteria);
}

$and = 'sl_and';

/**
 * A logical OR clause.
 *
 * This class is essentially a marker, as it does nothing other
 * than subclass the slCriteria base class.
 * 
 * @since 1.0.0-BETA
 */
final class slOrCriteria extends slCriteria {}

function sl_or($aCriteria) {
	$aCriteria = (is_array($aCriteria) ? $aCriteria : func_get_args());
	return new slOrCriteria($aCriteria);
}

$or = 'sl_or';

/**
 * A logical NOT clause.
 * 
 * This class inverts the purpose of the slCriteria objects it wraps.
 *
 * This class is essentially a marker, as it does nothing other
 * than subclass the slCriteria base class.
 *
 * @since 1.0.0-BETA
 */
class slNotCriteria extends slCriteria {}

function sl_not($aElements) {
	$aCriteria = (is_array($aCriteria) ? $aCriteria : func_get_args());
	return new slOrCriteria($aCriteria);
}

$not = 'sl_not';

class slIfCriteria extends slCriteria {

	private $condition;
	
	private $nextCase;
	
	function __construct($condition, slCriteria $criteria, slCriteria $nextCase = null) {
		$this->condition = $condition;
		$this->addCriteria($criteria);
		$this->nextCase = $nextCase;
	}
	
	function isTrue() {
		return $this->condition == true;
	}
	
	function nextCase() {
		return $this->nextCase;
	}
	
}

function sl_if($condition, slCriteria $criteria, slCriteria $nextCase = null) {
	return new slIfCriteria($condtion, $criteria, $nextCase);
}

$if = 'sl_if';

$elseif = 'sl_if';

$else = 'sl_criteria';

class slEachCriteria extends slCriteria {

	private $placeholder;
	
	private $values;
	
	private $criteria;
	
	function __construct($values, $placeholder, slCriteria $criteria) {
		$this->placeholder = $placeholder;
		$this->values = $values;
		$this->criteria = $criteria;
	}
	
	final function getPlaceholder() {
		return $this->placeholder;
	}
	
	final function getValues() {
		return $this->values;
	}
	
	final function getCriteria() {
		return $this->criteria;
	}
	
}

function sl_each($values, $placeholder, slCriteria $criteria) {
	return new slEachCriteria($values, $placeholder, $criteria);
}

$each = 'sl_each';

class slProjectionsCriteria extends slCriteria {}

function sl_projections($args) {
	$args = (is_array($args)) ? $args : func_get_args();
	return new slProjectionsCriteria($args);	
}

class slEqCriteria extends slCriteria {

	private $propertyName;
	
	private $value;
	
	function __construct($propertyName, $value) {
		$this->propertyName = $propertyName;
		$this->value = $value;
	}
	
	final function getPropertyName() {
		return $this->propertyName;
	}
	
	final function getValue() {
		return $this->value;
	}

}

function sl_eq($propertyName, $value) {
	return new slEqCriteria($propertyName, $value);
}

$eq = 'sl_eq';

class slNeCriteria extends slEqCriteria {}

function sl_ne($propertyName, $value) {
	return new slNeCriteria($propertyName, $value);
}

$ne = 'sl_ne';

class slLtCriteria extends slCriteria {}

function sl_lt($propertyName, $value) {
	return new slLtCriteria($propertyName, $value);
}

class slGtCriteria extends slCriteria {}

class slLeCriteria extends slCriteria {}

class slGeCriteria extends slCriteria {}

class slIsNullCriteria extends slCriteria {}

class slIsNotNullCriteria extends slCriteria {}

class slInListCriteria extends slCriteria {}

class slBetweenCriteria extends slCriteria {}

class slEqProperty extends slCriteria {}

class slNeProperty extends slCriteria {}

class slLtProperty extends slCriteria {}

class slLeProperty extends slCriteria {}

class slGtProperty extends slCriteria {}

class slGeProperty extends slCriteria {}

class slIdEq extends slCriteria {}

class slLike extends slCriteria {}

class slILike extends slCriteria {}

class slIsEmpty extends slCriteria {}

class slIsNotEmpty extends slCriteria {}

class slOrder extends slCriteria {}

class slRLike extends slCriteria {}

class slSizeEq extends slCriteria {}

class slSizeNe extends slCriteria {}

class slSizeGt extends slCriteria {}

class slSizeGe extends slCriteria {}

class slSizeLt extends slCriteria {}

class slSizeLe extends slCriteria {}

class slProperty extends slCriteria {}

class slDistinct extends slCriteria {}

class slAvg extends slCriteria {}

class slCount extends slCriteria {}

class slCountDistinct extends slCriteria {}

class slGroupProperty extends slCriteria {}

class slMax extends slCriteria {}

class slMin extends slCriteria {}

class slSum extends slCriteria {}

class slRowCount extends slCriteria {}

class slFirstResult extends slCriteria {}

class slMaxResults extends slCriteria {}



